{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "<a id='HOME'></a>\n",
    "# CHAPTER 4 Py Crust: Code Structures\n",
    "## Python外觀，代碼結構\n",
    "\n",
    "* [4.1 4.2 註解與連接](#Comment_Continue_Lines)\n",
    "* [4.3 使用if、elif與else進行邏輯判斷](#if_elif_else)\n",
    "* [4.4 使用while進行循環](#while)\n",
    "* [4.5 使用for迴圈](#for)\n",
    "* [4.6 Comprehensions 生成式](#comprehensions)\n",
    "* [4.7 Function 函數](#function)\n",
    "* [4.8 Generators 生成器](#Generators)\n",
    "* [4.9 Decorators 裝飾器](#Decorators)\n",
    "* [4.10 Namespaces and Scope 命名空間與作用區](#Namespaces)\n",
    "* [4.11 Handle Errors with try and except 處理錯誤](#TryAndExcept)\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "------\n",
    "<a id='Comment_Continue_Lines'></a>\n",
    "## 4.1 4.2 註解與連接\n",
    "[回目錄](#HOME)\n",
    "\n",
    "使用 _#_ 可以__註解__單行\n",
    "\n",
    "使用 _\\_ 可以__連接__多行"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "兩種不同的銜接多行方法:\n",
      "abcdefghijklmnopqrstuvwxyz\n",
      "abcdefghijklmnopqrstuvwxyz\n",
      "運算式也可以切斷\n",
      "6\n"
     ]
    }
   ],
   "source": [
    "# 我是註解，別理我\n",
    "\n",
    "print('兩種不同的銜接多行方法:')\n",
    "\n",
    "alphabet = ''\n",
    "alphabet += 'abcdefg'\n",
    "alphabet += 'hijklmnop'\n",
    "alphabet += 'qrstuv'\n",
    "alphabet += 'wxyz'\n",
    "print(alphabet)\n",
    "\n",
    "\n",
    "alphabet = 'abcdefg' + \\\n",
    "    'hijklmnop' + \\\n",
    "    'qrstuv' + \\\n",
    "    'wxyz'\n",
    "print(alphabet)\n",
    "\n",
    "print('運算式也可以切斷')\n",
    "a = 1 + 2 + \\\n",
    "    3\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "------\n",
    "<a id='if_elif_else'></a>\n",
    "## 4.3 使用if、elif與else進行邏輯判斷\n",
    "[回目錄](#HOME)\n",
    "\n",
    "__注意!!!記得使用冒號(：)做結尾!!!__\n",
    "\n",
    "使用4個空格做為區域劃分"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Woe!\n"
     ]
    }
   ],
   "source": [
    "disaster = True\n",
    "\n",
    "if disaster:\n",
    "    print(\"Woe!\")\n",
    "else:\n",
    "    print(\"Whee!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "It's a skink!\n"
     ]
    }
   ],
   "source": [
    "# 槽狀判斷式結構\n",
    "furry = False\n",
    "small = True\n",
    "\n",
    "if furry:\n",
    "    if small:\n",
    "        print(\"It's a cat.\")\n",
    "    else:\n",
    "        print(\"It's a bear!\")\n",
    "else:\n",
    "    if small:\n",
    "        print(\"It's a skink!\")\n",
    "    else:\n",
    "        print(\"It's a human. Or a hairless bear.\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "I've never heard of the color puce\n"
     ]
    }
   ],
   "source": [
    "# 值的判斷\n",
    "color = \"puce\"\n",
    "\n",
    "if color == \"red\":\n",
    "    print(\"It's a tomato\")\n",
    "elif color == \"green\":\n",
    "    print(\"It's a green pepper\")\n",
    "elif color == \"bee purple\":\n",
    "    print(\"I don't know what it is, but only bees can see it\")\n",
    "else:\n",
    "    print(\"I've never heard of the color\", color)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "------\n",
    "以下判斷結果會回傳 __True__ 或 __False__\n",
    "\n",
    "|  判斷式    | 判斷符號 |\n",
    "|-----------|:--------:|\n",
    "|  相等      |   ==    |\n",
    "|  不等於    |   !=    |\n",
    "|  小於      |   <     |\n",
    "|  小於等於  |   <=    |\n",
    "|  大於      |   >     |\n",
    "|  大於等於  |   >=    |\n",
    "|  屬於      |   in    |\n",
    "\n",
    "\n",
    "*and* 可以連接判斷結果，兩者都為True才會是True  \n",
    "*or*  前後兩者只要有一個為True就會回傳True  \n",
    "*not* 可以翻轉結果T → F 或是 F → T"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n",
      "True\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "x = 7\n",
    "print(5 < x or x < 10)\n",
    "print(5 < x and x > 10)\n",
    "print(5 < x and not x > 10)\n",
    "print(5 < x < 10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "------\n",
    "以下幾種在判斷時為__False__，其餘皆為__True__\n",
    "\n",
    "| 類型     |  值   |\n",
    "|---------|:-------:|\n",
    "| 布林值   | False |\n",
    "| null類型 | None  |\n",
    "| 整數     |  0    |\n",
    "| 浮點數   |   0.0 |\n",
    "| 空字串   |   ''  |\n",
    "| 空Tuples |   ()  |\n",
    "| 空Lists  |  []   |\n",
    "| 空Dictionaries|  {}  |\n",
    "| 空Set   |  set()  |\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hey, it's empty!\n"
     ]
    }
   ],
   "source": [
    "some_list = []\n",
    "if some_list:\n",
    "    print(\"There's something in here\")\n",
    "else:\n",
    "    print(\"Hey, it's empty!\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "------\n",
    "<a id='while'></a>\n",
    "## 4.4 使用while進行循環\n",
    "[回目錄](#HOME)\n",
    "\n",
    "一樣記得__分號__和__空4格__!!!\n",
    "\n",
    "使用__break__可以跳出循環  \n",
    "使用__continue__可以跳過此循環的後續，進行下一次循環  \n",
    "使用__else__可以判斷沒有使用__break__時的情況"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Case 1：一般使用while時\n",
      "1, 2, 3, 4, 5, \n",
      "\n",
      "Case 2：使用break，遇到3跳出迴圈\n",
      "1, 2, \n",
      "\n",
      "Case 3：使用continue，跳過值是3時\n",
      "1, 2, 4, 5, \n",
      "\n",
      "Case 4：使用else，若無使用break則執行段\n",
      "1, 2, 3, 4, 5, NO break!\n"
     ]
    }
   ],
   "source": [
    "print('Case 1：一般使用while時')\n",
    "count = 1\n",
    "while count <= 5:\n",
    "    print(count, end=', ')\n",
    "    count += 1\n",
    "\n",
    "\n",
    "print('\\n\\nCase 2：使用break，遇到3跳出迴圈')\n",
    "count = 1\n",
    "while count <= 5:\n",
    "    if count == 3:\n",
    "        break\n",
    "    print(count, end=', ')\n",
    "    count += 1\n",
    "\n",
    "\n",
    "print('\\n\\nCase 3：使用continue，跳過值是3時')\n",
    "count = 1\n",
    "while count <= 5:    \n",
    "    if count == 3:\n",
    "        count += 1\n",
    "        continue\n",
    "    print(count, end=', ')\n",
    "    count += 1\n",
    "\n",
    "print('\\n\\nCase 4：使用else，若無使用break則執行段')\n",
    "count = 1\n",
    "while count <= 5:\n",
    "    if count == 6:\n",
    "        break\n",
    "    print(count, end=', ')\n",
    "    count += 1\n",
    "else:\n",
    "    print('NO break!')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "------\n",
    "<a id='for'></a>\n",
    "## 4.5 使用for迴圈\n",
    "[回目錄](#HOME)\n",
    "\n",
    "還是老話一句!!記得__冒號__和__空4格__!!!\n",
    "\n",
    "python中頻繁的使用疊代器，可以遍歷整個容器結構，不須知道長度。就可以調出元素，符合python的精神!!\n",
    "\n",
    "一樣也可以使用__break, continue__ 與 __else__語法作為迴圈的控制"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "方法一：使用while方法遍歷每一個物件\n",
      "Flopsy\n",
      "Mopsy\n",
      "Cottontail\n",
      "Peter\n",
      "\n",
      "方法二：使用for方法遍歷每一個物件\n",
      "Flopsy\n",
      "Mopsy\n",
      "Cottontail\n",
      "Peter\n",
      "\n",
      "列舉出字串的每一個字母\n",
      "c\n",
      "a\n",
      "t\n",
      "\n",
      "列舉出Dictionaries中的每一個key值\n",
      "room\n",
      "person\n",
      "weapon\n",
      "\n",
      "列舉出Dictionaries中的每一個value值\n",
      "ballroom\n",
      "Col. Mustard\n",
      "lead pipe\n",
      "\n",
      "列舉出Dictionaries中的每一組物件，以Tuples輸出\n",
      "('room', 'ballroom')\n",
      "('person', 'Col. Mustard')\n",
      "('weapon', 'lead pipe')\n",
      "\n",
      "更改上面寫法，改為使用兩個參數去接key和value\n",
      "key： room ,\tvalue： ballroom\n",
      "key： person ,\tvalue： Col. Mustard\n",
      "key： weapon ,\tvalue： lead pipe\n"
     ]
    }
   ],
   "source": [
    "print('方法一：使用while方法遍歷每一個物件')\n",
    "rabbits = ['Flopsy', 'Mopsy', 'Cottontail', 'Peter']\n",
    "current = 0\n",
    "while current < len(rabbits):\n",
    "    print(rabbits[current])\n",
    "    current += 1\n",
    "\n",
    "print('\\n方法二：使用for方法遍歷每一個物件')\n",
    "for i in rabbits:\n",
    "    print(i)\n",
    "\n",
    "print('\\n列舉出字串的每一個字母')\n",
    "word = 'cat'\n",
    "for letter in word:\n",
    "    print(letter)\n",
    "\n",
    "print('\\n列舉出Dictionaries中的每一個key值')\n",
    "accusation = {'room': 'ballroom', 'weapon': 'lead pipe', 'person': 'Col. Mustard'}\n",
    "for card in accusation: # 或者是for card in accusation.keys():\n",
    "    print(card)\n",
    "\n",
    "print('\\n列舉出Dictionaries中的每一個value值')\n",
    "for value in accusation.values():\n",
    "    print(value)\n",
    "\n",
    "print('\\n列舉出Dictionaries中的每一組物件，以Tuples輸出')\n",
    "for item in accusation.items():\n",
    "    print(item)\n",
    "\n",
    "print('\\n更改上面寫法，改為使用兩個參數去接key和value')\n",
    "for card, contents in accusation.items():\n",
    "    print('key：', card, ',\\tvalue：', contents)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a\n",
      "b\n",
      "d\n",
      "e\n",
      "f\n"
     ]
    }
   ],
   "source": [
    "abc = 'abcdefghi'\n",
    "\n",
    "for chart in abc:\n",
    "    if chart == 'c':\n",
    "        continue\n",
    "    if chart == 'g':\n",
    "        break\n",
    "    print(chart)\n",
    "else:\n",
    "    print('g is not in here')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "------\n",
    "使用__zip()__進行可以對多組物件同時進行迴圈疊代!!!好用!!!  \n",
    "下面示範原本的方法和__zip()__的用法差異，優點在於自動以最__短__的物件做為參考，不會爆掉  \n",
    "__zip()__完的物件為tuple"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "原方法：\n",
      "Monday : drink coffee - eat banana - enjoy tiramisu\n",
      "Tuesday : drink tea - eat orange - enjoy ice cream\n",
      "Wednesday : drink beer - eat peach - enjoy pie\n",
      "\n",
      "zip()用法：\n",
      "Monday : drink coffee - eat banana - enjoy tiramisu\n",
      "Tuesday : drink tea - eat orange - enjoy ice cream\n",
      "Wednesday : drink beer - eat peach - enjoy pie\n"
     ]
    }
   ],
   "source": [
    "days = ['Monday', 'Tuesday', 'Wednesday']\n",
    "fruits = ['banana', 'orange', 'peach']\n",
    "drinks = ['coffee', 'tea', 'beer']\n",
    "desserts = ['tiramisu', 'ice cream', 'pie', 'pudding']\n",
    "\n",
    "print('原方法：')\n",
    "for i in range(len(days)):\n",
    "    print(days[i], \": drink\", drinks[i], \"- eat\", fruits[i], \"- enjoy\", desserts[i])\n",
    "\n",
    "print('\\nzip()用法：')\n",
    "for day, fruit, drink, dessert in zip(days, fruits, drinks, desserts):\n",
    "    print(day, \": drink\", drink, \"- eat\", fruit, \"- enjoy\", dessert)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false,
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "轉換成list包tuple\n",
      "[('Monday', 'Lundi'), ('Tuesday', 'Mardi'), ('Wednesday', 'Mercredi')]\n",
      "轉換成Dictionarie\n",
      "{'Tuesday': 'Mardi', 'Monday': 'Lundi', 'Wednesday': 'Mercredi'}\n"
     ]
    }
   ],
   "source": [
    "english = 'Monday', 'Tuesday', 'Wednesday'\n",
    "french = 'Lundi', 'Mardi', 'Mercredi'\n",
    "\n",
    "print('轉換成list包tuple')\n",
    "print(list( zip(english, french) ))\n",
    "print('轉換成Dictionarie')\n",
    "print(dict( zip(english, french) ))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "------\n",
    "使用__range()__產生自然數序列\n",
    "\n",
    "使用上如同__slices()：range( start, stop, step)__，start預設為0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Case1：疊代0~2\n",
      "0\n",
      "1\n",
      "2\n",
      "\n",
      "Case2：疊代2~0\n",
      "2\n",
      "1\n",
      "0\n",
      "\n",
      "Case3：也可以直接轉為list物件\n",
      "[0, 1, 2]\n",
      "[3, 2]\n"
     ]
    }
   ],
   "source": [
    "print('Case1：疊代0~2')\n",
    "for x in range(0,3):\n",
    "    print(x)\n",
    "\n",
    "print('\\nCase2：疊代2~0')\n",
    "for x in range(2, -1, -1):\n",
    "    print(x)\n",
    "\n",
    "print('\\nCase3：也可以直接轉為list物件')\n",
    "print(list( range(3) ))\n",
    "print(list( range(3, 1, -1) ))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----\n",
    "<a id='comprehensions'></a>\n",
    "## 4.6 Comprehensions 生成式\n",
    "[回目錄](#HOME)\n",
    "\n",
    "可以簡單漂亮的寫出python風格的語法  \n",
    "這些方法很好用，程式碼會更加的縮短且漂亮!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----\n",
    "### list的生成式\n",
    "\n",
    "```Python\n",
    "listObj = [expression for item in iterable if condition]\n",
    "```\n",
    "\n",
    "簡單來說_\"for item in iterable\"_為原本的for迴圈開頭  \n",
    "_\"if condition\"_為判斷式  \n",
    "_\"expression\"_為處理輸出結果  \n",
    "_\"[]\"_為轉換為list的部分\n",
    "\n",
    "不懂的話就直接看看以下範例吧~"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Case 1\n",
      "[1, 2, 3, 4, 5]\n",
      "\n",
      "Case 2\n",
      "[1, 2, 3, 4, 5]\n",
      "\n",
      "Case 3\n",
      "[1, 2, 3, 4, 5]\n",
      "\n",
      "Case 4\n",
      "[1, 2, 3, 4, 5]\n"
     ]
    }
   ],
   "source": [
    "# 目標創建一個list，包含1~5\n",
    "\n",
    "# 在學到第三章時你要創造一個list可能會使用以下方法\n",
    "print('Case 1')\n",
    "number_list = []\n",
    "number_list.append(1)\n",
    "number_list.append(2)\n",
    "number_list.append(3)\n",
    "number_list.append(4)\n",
    "number_list.append(5)\n",
    "print(number_list)\n",
    "\n",
    "# 再稍微前面的一點時你會學到用for迴圈處理\n",
    "print('\\nCase 2')\n",
    "number_list = []\n",
    "for number in range(1, 6):\n",
    "    number_list.append(number)\n",
    "print(number_list)\n",
    "\n",
    "# 或是把list用上\n",
    "print('\\nCase 3')\n",
    "print(list(range(1, 6)))\n",
    "\n",
    "# 但是，這邊起提供一個更為漂亮的寫法，而且靈活度高\n",
    "print('\\nCase 4')\n",
    "print([number for number in range(1,6)])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 3, 5]\n",
      "[1, 3, 5]\n",
      "[1, 3, 5]\n"
     ]
    }
   ],
   "source": [
    "# 可以對expression部分進行運算處理\n",
    "print([number*2 - 3 for number in range(2,5)])\n",
    "\n",
    "# 可以放置if判斷式\n",
    "print([number for number in range(1,6) if number % 2 == 1])\n",
    "\n",
    "# 上面那個改成正常迴圈的寫法如下，你喜歡哪個呢?\n",
    "a_list = []\n",
    "for number in range(1,6):\n",
    "    if number % 2 == 1:\n",
    "        a_list.append(number)\n",
    "print(a_list)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 1\n",
      "1 2\n",
      "2 1\n",
      "2 2\n",
      "3 1\n",
      "3 2\n",
      "----\n",
      "1 1\n",
      "1 2\n",
      "2 1\n",
      "2 2\n",
      "3 1\n",
      "3 2\n"
     ]
    }
   ],
   "source": [
    "# 巢狀迴圈也可以使用隱含式辦到\n",
    "# 巢狀的順序就按照出現的順序依序往內\n",
    "\n",
    "rows = range(1,4)\n",
    "cols = range(1,3)\n",
    "cells = []\n",
    "for row in rows:\n",
    "    for col in cols:\n",
    "        cells.append((row, col))\n",
    "for cell_r, cell_c in cells:\n",
    "    print(cell_r, cell_c)\n",
    "\n",
    "print('----')\n",
    "# 隱含式版本\n",
    "cells = [(r,c) for r in range(1, 4) for c in range(1, 3)]\n",
    "for cell_r, cell_c in cells:\n",
    "    print(cell_r, cell_c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "### dictionary生成式\n",
    "\n",
    "```Python\n",
    "dictionaryObj = { key_expression : value_expression for expression in iterable if condition}\n",
    "```\n",
    "\n",
    "_for expression in iterable_為for迴圈部分  \n",
    "*key_expression*為key值  \n",
    "*value_expression*為value值  \n",
    "*if condition*為判斷式  \n",
    "_{}_ 表示為一個dictionary"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'r': 1, 't': 2, 's': 1, 'l': 1}\n",
      "{'啦', '睡', '洗'}\n"
     ]
    }
   ],
   "source": [
    "# 計算一個單字裡子音字母的出現次數\n",
    "# 使用Set排除重複子母\n",
    "\n",
    "word = 'letters'\n",
    "letter_counts = {letter: word.count(letter) for letter in set(word) if letter.lower() not in 'aeiou'}\n",
    "print(letter_counts)\n",
    "\n",
    "oneway = \"洗洗睡啦\"\n",
    "print(set(oneway))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "### set生成式\n",
    "\n",
    "```Python\n",
    "set_Obj = {expression for expression in iterable if condition}\n",
    "```\n",
    "\n",
    "如同list的使用方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1, 4}"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "{number for number in range(1,6) if number % 3 == 1}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "### generator生成器\n",
    "\n",
    "tuples沒有隱含式的用法，使用()包起來是generator的用法  \n",
    "簡單來說就是可以產生像是_range()_的物件，亦表示可以直接對其疊代\n",
    "\n",
    "__記住!!!generator只能使用一次!!!__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1,)\n",
      "<generator object <genexpr> at 0x0000019265E8CBA0>\n",
      "1\n",
      "4\n",
      "7\n",
      "10\n",
      "13\n",
      "[]\n",
      "因為只能使用一次，所以上面這邊找不到東西了\n",
      "[1, 4, 7, 10, 13]\n"
     ]
    }
   ],
   "source": [
    "number_thing = (number*3-2 for number in range(1, 6))\n",
    "print((1,))\n",
    "print(number_thing)\n",
    "for number in number_thing:\n",
    "    print(number)\n",
    "\n",
    "# 或者轉為一個list做為使用\n",
    "number_list = list(number_thing)\n",
    "print(number_list)\n",
    "print('因為只能使用一次，所以上面這邊找不到東西了')\n",
    "\n",
    "\n",
    "number_thing = (number*3-2 for number in range(1, 6))\n",
    "number_list = list(number_thing)\n",
    "print(number_list)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "<a id='function'></a>\n",
    "## 4.7 Function 函數\n",
    "[回目錄](#HOME)\n",
    "\n",
    "目的，重複使用程式碼，將程式模組化，方便維護管理\n",
    "\n",
    "* 定義函數\n",
    "* 呼叫函數\n",
    "\n",
    "一樣記得__冒號__和__空四格__!!\n",
    "\n",
    "不一定要_return_，但有_return_一定要有變數接住他，或是使用他。若此function沒有return則回傳__None__\n",
    "\n",
    "```python\n",
    "def function_name():\n",
    "    return some\n",
    "    \n",
    "result = function_name()\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "quack\n",
      "True\n",
      "Splendid!\n",
      "HEY~ HEY~\n",
      "I've never heard of the color blue.\n",
      "quack\n",
      "None\n"
     ]
    }
   ],
   "source": [
    "# 宣告function\n",
    "def make_a_sound():\n",
    "    print('quack')\n",
    "\n",
    "def agree():\n",
    "    return True\n",
    "\n",
    "# 使用function\n",
    "make_a_sound()\n",
    "\n",
    "# 用變數接住\n",
    "isagree = agree()\n",
    "print(isagree)\n",
    "\n",
    "# 或是直接使用返回值\n",
    "if agree():\n",
    "    print('Splendid!')\n",
    "else:\n",
    "    print('That was unexpected.')\n",
    "\n",
    "# return的型態不限\n",
    "def echo(anything):\n",
    "    return anything + ' ' + anything\n",
    "\n",
    "print(echo('HEY~'))\n",
    "\n",
    "def commentary(color):\n",
    "    if color == 'red':\n",
    "        return \"It's a tomato.\"\n",
    "    elif color == \"green\":\n",
    "        return \"It's a green pepper.\"\n",
    "    elif color == 'bee purple':\n",
    "        return \"I don't know what it is, but only bees can see it.\"\n",
    "    else:\n",
    "        return \"I've never heard of the color \" + color + \".\"\n",
    "\n",
    "print(commentary('blue'))\n",
    "\n",
    "# 若此function沒有return則回傳None\n",
    "print(make_a_sound())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "### 位置參數與關鍵字參數\n",
    "\n",
    "要把參數傳進function中有兩種方法，位置參數與關鍵字參數，範例如下\n",
    "(如果同時出現，則以位置參數優先)\n",
    "\n",
    "可以在宣告函數時，設定預設值，若使用function時沒有填入該項目，則使用預設值，有的話則覆蓋"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'wine': 'chardonnay', 'dessert': 'cake', 'entree': 'chicken'}\n",
      "{'wine': 'bordeaux', 'dessert': 'bagel', 'entree': 'beef'}\n",
      "{'wine': 'frontenac', 'dessert': 'flan', 'entree': 'fish'}\n"
     ]
    }
   ],
   "source": [
    "def menu(wine, entree, dessert):\n",
    "    return {'wine': wine, 'entree': entree, 'dessert': dessert}\n",
    "            \n",
    "print(menu('chardonnay', 'chicken', 'cake'))\n",
    "print(menu(entree='beef', dessert='bagel', wine='bordeaux'))\n",
    "print(menu('frontenac', dessert='flan', entree='fish'))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'wine': 'chardonnay', 'dessert': 'pudding', 'entree': 'chicken'}\n",
      "{'wine': 'dunkelfelder', 'dessert': 'doughnut', 'entree': 'duck'}\n"
     ]
    }
   ],
   "source": [
    "def menu(wine, entree, dessert='pudding'):\n",
    "    return {'wine': wine, 'entree': entree, 'dessert': dessert}\n",
    "\n",
    "print(menu('chardonnay', 'chicken'))\n",
    "print(menu('dunkelfelder', 'duck', 'doughnut'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['a']\n",
      "['a', 'b']\n",
      "['a']\n",
      "['b']\n"
     ]
    }
   ],
   "source": [
    "# 特別注意!!!!若把空list當作預設值會發生預期之外的事情\n",
    "def buggy(arg, result=[]):\n",
    "    result.append(arg)\n",
    "    print(result)\n",
    "\n",
    "# 第一次使用時OK\n",
    "buggy('a')\n",
    "# 第二次使用時就會殘存上次的結果\n",
    "buggy('b')\n",
    "\n",
    "\n",
    "# 可以使用以下方法修改function\n",
    "def works(arg):\n",
    "    result = []\n",
    "    result.append(arg)\n",
    "    return result\n",
    "\n",
    "def nonbuggy(arg, result=None):\n",
    "    if result is None:\n",
    "        result = []\n",
    "    result.append(arg)\n",
    "    print(result)\n",
    "\n",
    "works('a')\n",
    "works('b')\n",
    "\n",
    "nonbuggy('a')\n",
    "nonbuggy('b')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----\n",
    "### 使用 \\* 與 \\*\\* 收集位置參數與關鍵字參數\n",
    "\n",
    "\\*收集而成的參數會以Tuples儲存  \n",
    "\\*\\*收集到的會以Dictionary儲存"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "全部都給收集器\n",
      "Positional argument tuple: ()\n",
      "Positional argument tuple: (1, 2, 3)\n",
      "\n",
      "混合位置參數使用，剩下的都給收集器\n",
      "Need this one: cap\n",
      "Need this one too: gloves\n",
      "All the rest: ('scarf', 'monocle', 'mustache wax')\n"
     ]
    }
   ],
   "source": [
    "print('全部都給收集器')\n",
    "def print_args(*args):\n",
    "    print('Positional argument tuple:', args)\n",
    "    \n",
    "print_args()\n",
    "print_args(1,2,3)\n",
    "\n",
    "\n",
    "print('\\n混合位置參數使用，剩下的都給收集器')\n",
    "def print_more(required1, required2, *args):\n",
    "    print('Need this one:', required1)\n",
    "    print('Need this one too:', required2)\n",
    "    print('All the rest:', args)\n",
    "    \n",
    "print_more('cap', 'gloves', 'scarf', 'monocle', 'mustache wax')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Keyword arguments: {'wine': 'merlot', 'dessert': 'macaroon', 'entree': 'mutton'}\n"
     ]
    }
   ],
   "source": [
    "def print_kwargs(**kwargs):\n",
    "    print('Keyword arguments:', kwargs)\n",
    "    \n",
    "print_kwargs(wine='merlot', entree='mutton', dessert='macaroon')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "### function 說明文字\n",
    "\n",
    "為了提高程式的可讀性，可以對自行定義出的函數加上說明文字，他人在使用時就可以使用help叫出文字"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on function echo in module __main__:\n",
      "\n",
      "echo(anything)\n",
      "    echo returns its input argument\n",
      "\n",
      "--------------------------------\n",
      "Help on function print_if_true in module __main__:\n",
      "\n",
      "print_if_true(thing, check)\n",
      "    Prints the first argument if a second argument is true.\n",
      "    The operation is:\n",
      "    1. Check whether the *second* argument is true.\n",
      "    2. If it is, print the *first* argument.\n",
      "\n",
      "\n",
      "僅叫出文字↓\n",
      "echo returns its input argument\n",
      "--------------------------------\n",
      "\n",
      "Prints the first argument if a second argument is true.\n",
      "The operation is:\n",
      "1. Check whether the *second* argument is true.\n",
      "2. If it is, print the *first* argument.\n",
      "    \n"
     ]
    }
   ],
   "source": [
    "def echo(anything):\n",
    "    'echo returns its input argument'\n",
    "    return anything\n",
    "\n",
    "def print_if_true(thing, check):\n",
    "    '''\n",
    "Prints the first argument if a second argument is true.\n",
    "The operation is:\n",
    "1. Check whether the *second* argument is true.\n",
    "2. If it is, print the *first* argument.\n",
    "    '''\n",
    "    if check:\n",
    "        print(thing)\n",
    "\n",
    "help(echo)\n",
    "print('--------------------------------')\n",
    "help(print_if_true)\n",
    "\n",
    "print('\\n僅叫出文字↓')\n",
    "print(echo.__doc__)\n",
    "print('--------------------------------')\n",
    "print(print_if_true.__doc__)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "### 一等公民：function\n",
    "在python的設計中，function是一級公民。  \n",
    "換句話說python是物件導向的語言，所有的東西都是物件，連function也是。\n",
    "\n",
    "所以說function可以當成參數傳入其他function，也可以將function當成結果回傳。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "8"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def run_something(func, a, b):\n",
    "    print(func(a, b))\n",
    "    \n",
    "def add(a, b):\n",
    "    return a + b\n",
    "\n",
    "run_something(add, 2, 3)\n",
    "\n",
    "test = add\n",
    "test(3,5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----\n",
    "### 內部函數\n",
    "\n",
    "function內部可以在在宣告function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "11"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def outer(a, b):\n",
    "    def inner(c, d):\n",
    "        return c + d\n",
    "    return inner(a, b)\n",
    "\n",
    "outer(4, 7)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----\n",
    "### 閉包\n",
    "\n",
    "可以動態生成函數，可用來記錄外部傳入的變數"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "We are the knights who say: 'XDD'\n"
     ]
    }
   ],
   "source": [
    "def knights2(saying):\n",
    "    def inner2():\n",
    "        return \"We are the knights who say: '%s'\" % saying\n",
    "    return inner2\n",
    "\n",
    "a = knights2('XDD')\n",
    "print(a())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "### 匿名函數：lambda()\n",
    "\n",
    "當想要傳入一個小function作為使用時，卻又不想宣告出來，可以使用匿名函數"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Thud!\n",
      "Meow!\n",
      "Thud!\n",
      "Hiss!\n",
      "-----\n",
      "Thud!\n",
      "Meow!\n",
      "Thud!\n",
      "Hiss!\n"
     ]
    }
   ],
   "source": [
    "def edit_story(words, func):\n",
    "    for word in words:\n",
    "        print(func(word))\n",
    "        \n",
    "stairs = ['thud', 'meow', 'thud', 'hiss']\n",
    "\n",
    "def enliven(word):\n",
    "    return word.capitalize() + '!'\n",
    "\n",
    "# 原做法\n",
    "edit_story(stairs, enliven)\n",
    "\n",
    "print('-----')\n",
    "\n",
    "# 匿名函數作法\n",
    "edit_story(stairs, lambda word: word.capitalize() + '!')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "------\n",
    "<a id='Generators'></a>\n",
    "## 4.8 Generators 生成器\n",
    "[回目錄](#HOME)\n",
    "\n",
    "生成器式用來創建一個序列物件，但是又可以不用事前將一整個序列存進記憶體中擺放，會隨著每一次執行而改變數值\n",
    "\n",
    "每次疊代生成器時，它會記錄上一次調用的位置，並且返回下一個值。  \n",
    "這一點和普通的函數是不一樣的，一般函數都不記錄前一次調用，而且都會在函數的第一行開始執行。\n",
    "\n",
    "內建的__range()__就是一種生成器。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "------\n",
      "<function my_range at 0x0000019265EB70D0>\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n"
     ]
    }
   ],
   "source": [
    "# 自製range函數\n",
    "def my_range(first=0, last=10, step=1):\n",
    "    number = first\n",
    "    while number < last:\n",
    "        yield number\n",
    "        number += step\n",
    "        \n",
    "ranger = my_range(1, 5)\n",
    "for x in ranger:\n",
    "    print(x)\n",
    "\n",
    "print('------')\n",
    "print(my_range)\n",
    "for x in my_range(1, 5):\n",
    "    print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "------\n",
    "<a id='Decorators'></a>\n",
    "## 4.9 Decorators 裝飾器\n",
    "[回目錄](#HOME)\n",
    "\n",
    "用來修改已經存在的函數，可以針對結果進行再次包裝處理產生新的函數\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "---------原函數結果----------\n",
      "8\n",
      "\n",
      "---------人工附值------------\n",
      "Running function: add_ints\n",
      "Positional arguments: (3, 5)\n",
      "Keyword arguments: {}\n",
      "Result: 8\n",
      "8\n",
      "\n",
      "---------直接添加裝飾器------\n",
      "Running function: add_ints2\n",
      "Positional arguments: (3, 5)\n",
      "Keyword arguments: {}\n",
      "Result: 8\n",
      "8\n",
      "\n",
      "---------套用一個以上的裝飾器-\n",
      "Running function: new_function\n",
      "Positional arguments: (3, 5)\n",
      "Keyword arguments: {}\n",
      "Result: 64\n",
      "64\n",
      "\n",
      "交換裝飾器順序，若新的處理過程是可以做乘除交換則結果不變，但過程會變\n",
      "Running function: add_ints\n",
      "Positional arguments: (3, 5)\n",
      "Keyword arguments: {}\n",
      "Result: 8\n",
      "64\n"
     ]
    }
   ],
   "source": [
    "# 裝飾器1\n",
    "def document_it(func):\n",
    "    def new_function(*args, **kwargs):\n",
    "        print('Running function:', func.__name__)\n",
    "        print('Positional arguments:', args)\n",
    "        print('Keyword arguments:', kwargs)\n",
    "        result = func(*args, **kwargs)\n",
    "        print('Result:', result)\n",
    "        return result\n",
    "    return new_function\n",
    "        \n",
    "        \n",
    "def add_ints(a, b):\n",
    "    return a + b\n",
    "\n",
    "print('---------原函數結果----------')\n",
    "print(add_ints(3, 5))\n",
    "\n",
    "print('\\n---------人工附值------------')\n",
    "cooler_add_ints = document_it(add_ints)\n",
    "print(cooler_add_ints(3, 5))\n",
    "\n",
    "print('\\n---------直接添加裝飾器------')\n",
    "@document_it\n",
    "def add_ints2(a, b):\n",
    "    return a + b\n",
    "print(add_ints2(3, 5))\n",
    "\n",
    "# 裝飾器2\n",
    "def square_it(func):\n",
    "    def new_function(*args, **kwargs):\n",
    "        result = func(*args, **kwargs)\n",
    "        return result * result\n",
    "    return new_function\n",
    "\n",
    "print('\\n---------套用一個以上的裝飾器-')\n",
    "@document_it\n",
    "@square_it\n",
    "def add_ints(a, b):\n",
    "    return a + b\n",
    "\n",
    "print(add_ints(3, 5))\n",
    "\n",
    "print('\\n交換裝飾器順序，若新的處理過程是可以做乘除交換則結果不變，但過程會變')\n",
    "@square_it\n",
    "@document_it\n",
    "def add_ints(a, b):\n",
    "    return a + b\n",
    "\n",
    "print(add_ints(3, 5))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "------\n",
    "<a id='Namespaces'></a>\n",
    "## 4.10 Namespaces and Scope 命名空間與作用區\n",
    "[回目錄](#HOME)\n",
    "\n",
    "\n",
    "在主程式(main)中的變數稱為全域變數，可以在函數中呼叫到，但不能改變他。\n",
    "\n",
    "在函數內出現與全域變數相同名稱的變數則是另一個不同的變數，則可以改變值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "可以在函數內呼叫到全域變數。\n",
      "inside print_global: fruitbat\n",
      "但無法改變他，會出錯。\n",
      "\n",
      "若要在函數內使用相同名稱的變數，且需不同於全域變數，必須先賦予值方可使用。\n",
      "inside change_and_print_global: wombat\n",
      "\n",
      "若是在函數內想改變全域變數則使用 global即可\n",
      "inside change_and_print_global: wombat\n",
      "\n",
      "外面的同時也會被改變 wombat\n"
     ]
    }
   ],
   "source": [
    "animal = 'fruitbat'\n",
    "def print_global():\n",
    "    print('inside print_global:', animal)\n",
    "\n",
    "print('可以在函數內呼叫到全域變數。')\n",
    "print_global()\n",
    "\n",
    "\n",
    "def change_and_print_global():\n",
    "#     print('inside change_and_print_global:', animal)\n",
    "    animal = 'wombat'\n",
    "    \n",
    "print('但無法改變他，會出錯。')\n",
    "# 可以嘗試取消下行註解試試看\n",
    "# change_and_print_global()\n",
    "\n",
    "def change_and_print_global():\n",
    "    animal = 'wombat'\n",
    "    print('inside change_and_print_global:', animal)\n",
    "\n",
    "print('\\n若要在函數內使用相同名稱的變數，且需不同於全域變數，必須先賦予值方可使用。')\n",
    "change_and_print_global()\n",
    "\n",
    "print('\\n若是在函數內想改變全域變數則使用 global即可')\n",
    "def change_and_print_global():\n",
    "    global animal\n",
    "    animal = 'wombat'\n",
    "    print('inside change_and_print_global:', animal)\n",
    "\n",
    "change_and_print_global()\n",
    "print('\\n外面的同時也會被改變', animal)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "------\n",
    "<a id='TryAndExcept'></a>\n",
    "## 4.11 Handle Errors with try and except 處理錯誤\n",
    "[回目錄](#HOME)\n",
    "\n",
    "程式在出現錯誤時可以確保他繼續執行下去不會停擺!!! 也有人用來測試函數存在與否用\n",
    "\n",
    "```python\n",
    "try:\n",
    "    #執行的內容\n",
    "except:\n",
    "    #錯誤後執行的內容\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Need a position between 0 and 2  but got 5\n",
      "1\n",
      "2\n",
      "3\n",
      "Bad index: list index out of range\n",
      "Something else broke: invalid literal for int() with base 10: 'two'\n"
     ]
    }
   ],
   "source": [
    "short_list = [1, 2, 3]\n",
    "position = 5\n",
    "try:\n",
    "    short_list[position]\n",
    "except:\n",
    "    print('Need a position between 0 and', len(short_list)-1, ' but got',position)\n",
    "    \n",
    "    \n",
    "# 有一些內建的錯誤捕捉方法可以使用\n",
    "def interr(value):\n",
    "    short_list = [1, 2, 3]\n",
    "    try:\n",
    "        position = int(value)\n",
    "        print(short_list[position])\n",
    "    except IndexError as err:\n",
    "        print('Bad index:', err)\n",
    "    except Exception as other:\n",
    "        print('Something else broke:', other)\n",
    "\n",
    "interr(0)\n",
    "interr(1)\n",
    "interr(2)\n",
    "interr(3)\n",
    "interr('two')"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [Root]",
   "language": "python",
   "name": "Python [Root]"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
